from src.db_utils import *
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

def get_dynamic_element(driver, base_xpath, index=1, timeout=50):
    """定位带索引的动态元素（适配多条工时条目）"""
    try:
        full_xpath = base_xpath.format(index=index)
        return WebDriverWait(driver, timeout).until(
            EC.element_to_be_clickable((By.XPATH, full_xpath))
        )
    except Exception as e:
        print(f"定位元素失败（XPath: {full_xpath}，索引: {index}）：{str(e)}")
        raise

def select_ticket_with_keys(driver, code_xpath, entry_index, ticket_code):
    concrete_xpath = code_xpath.format(index=entry_index)
    input_element = get_dynamic_element(driver, concrete_xpath, entry_index)
    input_element.send_keys(ticket_code)
    time.sleep(3)

    # 按下↓键选择第一个选项，再按Enter确认
    input_element.send_keys(Keys.DOWN)  # 向下箭头选中第一个选项
    time.sleep(1)
    input_element.send_keys(Keys.ENTER)  # 确认选择
    print(f"通过键盘操作选择：{ticket_code}")

def add_work_time(button_id):
    db = None
    driver = None
    current_driver_type = ""

    try:
        # 1. 数据库初始化与工单查询
        db = Database()
        c = db.get_connection()
        valid_worktimes = ['其他', '培训', '会议', '渠道支持', '竞品分析', '市场活动']
        all_tickets = []
        driver_type_map = {
            "add_worktime": "departtime",
            "add_tikettime": "tickettime",
        }
        current_driver_type = driver_type_map.get(button_id, "")
        if not current_driver_type:
            print("无效的按钮ID")
            return

        # 2. 根据按钮类型，构造不同查询条件（核心修改）
        if button_id == "add_worktime":
            # 查询的是 ticket_time 自身的 id（主键），不是 ticket 表的 ticket_id
            ticket_query = """
                SELECT id, ticket_code, work_contect, start_time, use_time, is_worktime
                FROM ticket_time 
                WHERE  (is_del <> '1' OR is_del is null) AND (ticket_time_status <> '1' OR ticket_time_status IS NULL) 
                  AND is_worktime IN ({})
            """.format(', '.join(['?'] * len(valid_worktimes)))
            c.execute(ticket_query, valid_worktimes)
            all_tickets = c.fetchall()
            driver_type_name = "部门工时"
        elif button_id == "add_tikettime":
            ticket_query = """
                SELECT id, ticket_code, work_contect, start_time, use_time, is_worktime
                FROM ticket_time 
                WHERE is_worktime = '工单' AND (is_del <> '1' OR is_del is null) AND (ticket_time_status <> '1' OR ticket_time_status IS NULL)
            """
            c.execute(ticket_query)
            all_tickets = c.fetchall()
            driver_type_name = "工单工时"
        # elif button_id == "add_projecttime":
        #     driver = get_projecttimedriver()
        #     wait = WebDriverWait(driver, 50)
        #     time.sleep(20)

        # 3. 检查待处理数据
        total = len(all_tickets)
        if total == 0:
            print(f"无待处理{driver_type_name}数据，退出程序")
            return
        print(f"共查询到 {total} 条{driver_type_name}数据，开始批量添加工时...")

        # 4. 初始化对应浏览器（按按钮类型区分）
        driver = get_driver(current_driver_type, use_existing_browser=True)
        wait = WebDriverWait(driver, 50)
        time.sleep(8)

        # 5. 循环处理每条数据（复用填写逻辑，页面差异可在此处微调）
        for entry_index, time_record in enumerate(all_tickets, 1):
            ticket_time_id, ticket_code, work_contect, start_time, use_time, is_worktime = time_record
            print(f"\n处理第 {entry_index}/{total} 条数据：ID={ticket_time_id}，工单编号={ticket_code}")

            try:
                if button_id == "add_worktime":
                    # 5.1 点击【添加】按钮，新增工时条目
                    add_btn = wait.until(EC.element_to_be_clickable(
                        (By.XPATH, '(//*[@id="widget_1136954676027326469"])/div[1]/div[1]/div[1]/div[2]/span[1]')
                    ))
                    add_btn.click()
                    time.sleep(1.5)  # 等待条目渲染
                    
                    # 5.2 填写数据（若两个页面XPath有差异，用 if button_id 判断修改）
                    # 日期输入框
                    date_xpath = '(//*[@id="widget_1136955406113046529" and @data-id="c8e1390f983445da9e7fa2a94562f8b6"])[{index}]/div/div/div/div/div/div/input'
                    get_dynamic_element(driver, date_xpath, entry_index).send_keys(start_time)

                    # 工时类型选择
                    type_xpath = '(//*[@id="widget_1158401797233459274" and @data-id="d15e822894ef4a6daf561c6f7b4ea37e"])[{index}]/div/div/div/div/div/div'
                    get_dynamic_element(driver, type_xpath, entry_index).click()
                    option_xpath = f'//li[@class="ui-select-option" and @title="{is_worktime}"]'
                    wait.until(EC.element_to_be_clickable((By.XPATH, option_xpath))).click()
                    time.sleep(0.5)

                    # 工时时长
                    time_xpath = '(//*[@fieldid="1136955406113046530" and @placeholder="请输入工时时长"])[{index}]'
                    get_dynamic_element(driver, time_xpath, entry_index).send_keys(str(use_time))

                    # 工时描述
                    desc_xpath = '(//*[@id="widget_1136955406113046531" and @data-id="f01cc5dcec4f4eb0b77ef985b2edf9b1"])[{index}]/div/div/div/div/textarea'
                    get_dynamic_element(driver, desc_xpath, entry_index).send_keys(work_contect)

                if button_id == "add_tikettime":
                    # 5.1 点击【添加】按钮，新增工时条目
                    add_btn = wait.until(EC.element_to_be_clickable(
                        (By.XPATH, '(//*[@id="widget_1136952605995696134"])/div[1]/div[1]/div[1]/div[2]/span[1]')
                    ))
                    add_btn.click()
                    time.sleep(1.5)  # 等待条目渲染
                    # 5.2 填写数据
                    # 工单编号
                    code_xpath = '(//*[@id="ce975501db904f47a4aa8dff5b7519ed"])[{index}]/div/div/div/div/span/div/div/div/input'
                    select_ticket_with_keys(driver, code_xpath, entry_index, ticket_code)
                    print(f"已成功选择工单编号：{ticket_code}")
                    # 日期输入框
                    date_xpath = '(//*[@id="widget_1193934894697210240" and @data-id="c839a2543c124d1fac14115492a3f9dd"])[{index}]/div/div/div/div/div/div/input'
                    get_dynamic_element(driver, date_xpath, entry_index).send_keys(start_time)

                    # 工时时长
                    time_xpath = '(//*[@fieldid="1136952605995696152" and @placeholder="请输入工时时长"])[{index}]'
                    get_dynamic_element(driver, time_xpath, entry_index).send_keys(str(use_time))

                    # 工时描述
                    desc_xpath = '(//*[@id="widget_1136952605995696135" and @data-id="b274f2f3e0074bf897dd7570ffe9ad4a"])[{index}]/div/div/div/div/textarea'
                    get_dynamic_element(driver, desc_xpath, entry_index).send_keys(work_contect)


                # 5.3 标记为已处理
                c.execute("UPDATE ticket_time SET ticket_time_status = 1 WHERE id = ?", (ticket_time_id,))
                db.commit_database()
                print(f"第 {entry_index} 条数据填写完成")

            except Exception as e:
                print(f"处理数据 {ticket_time_id} 失败：{str(e)}")
                # db.rollback_database()
                continue

        # 6. 保存数据（仅点击一次）
        print(f"\n所有{driver_type_name}条目填写完毕，开始保存...")
        if button_id == "add_worktime":
            save_btn = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//button[@appid="1020021532740116481" and @data-id="1136954199277568002"]')
            ))
        if button_id == "add_tikettime":
            save_btn = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//button[@appid="1020021532740116481" and @data-id="1136952648760819717"]')
            ))
        driver.execute_script("arguments[0].scrollIntoView(true); arguments[0].click();", save_btn)
        time.sleep(5)
        print(f"{driver_type_name}保存成功！")

    except sqlite3.Error as db_err:
        print(f"数据库错误：{db_err}")
    except Exception as general_err:
        print(f"程序执行错误：{general_err}")
    finally:
        # 资源释放
        if db:
            db.close_connection()
        # if current_driver_type:
        #     release_driver(current_driver_type)
        print("\n程序结束")